"""Email sender for review reports."""

import logging
import smtplib
import email.utils
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from typing import List

from ..config import EmailConfig
from ..models import ReviewResult

logger = logging.getLogger(__name__)


class EmailSender:
    """Email sender for review reports."""

    def __init__(self, config: EmailConfig):
        """
        Initialize email sender.

        Args:
            config: Email configuration
        """
        self.config = config
        # Determine if SSL should be used based on port
        # Port 465 typically uses SSL, port 587 uses TLS
        self.use_ssl = config.smtp_port == 465

    def should_send_email(self, severity: str, review_config: dict) -> bool:
        """
        Determine if email should be sent based on severity.

        Args:
            severity: Review severity level
            review_config: Review configuration

        Returns:
            True if email should be sent
        """
        severity_levels = review_config.get("severity_levels", [])
        for level in severity_levels:
            if level.get("name") == severity:
                return level.get("send_email", False)
        return False

    def generate_email_body(self, result: ReviewResult) -> str:
        """
        Generate email body text (brief summary).

        Args:
            result: ReviewResult object

        Returns:
            Plain text email body
        """
        severity_emoji = {
            "critical": "🔴",
            "high": "🟠",
            "medium": "🟡",
            "low": "🟢",
        }
        emoji = severity_emoji.get(result.severity, "📝")
        
        body = f"""
您好，

这是一份自动生成的代码审查报告。

PR 信息:
- 仓库: {result.repo_name}
- PR 编号: #{result.pr_number}
- 标题: {result.pr_title}
- 链接: {result.pr_url}
- 严重程度: {emoji} {result.severity.upper()}
- 评分: {result.severity_score:.2f}/1.0

审查总结:
{result.summary}

详细审查报告请查看附件中的 Markdown 文件。

---
本报告由自动代码审查工具生成
        """.strip()
        
        return body

    def send_email_with_attachment(
        self, subject: str, body_text: str, markdown_content: str, 
        attachment_filename: str, to_addresses: List[str]
    ) -> bool:
        """
        Send email with Markdown file as attachment.

        Args:
            subject: Email subject
            body_text: Plain text email body
            markdown_content: Markdown content to attach
            attachment_filename: Name of the attachment file
            to_addresses: List of recipient email addresses

        Returns:
            True if email sent successfully
        """
        try:
            # Create multipart message
            message = MIMEMultipart()
            
            # Format sender and receiver addresses
            # Extract display name and email from from_address if format is "Name <email>"
            from_parts = self.config.from_address.split("<")
            if len(from_parts) == 2:
                from_name = from_parts[0].strip().strip('"')
                from_email = from_parts[1].strip().rstrip(">")
            else:
                from_name = "Auto Review"
                from_email = self.config.from_address
            
            message["From"] = email.utils.formataddr((from_name, from_email))
            
            # Format recipients
            recipient_list = []
            for addr in to_addresses:
                # Extract display name and email if format is "Name <email>"
                addr_parts = addr.split("<")
                if len(addr_parts) == 2:
                    name = addr_parts[0].strip().strip('"')
                    email_addr = addr_parts[1].strip().rstrip(">")
                    recipient_list.append(email.utils.formataddr((name, email_addr)))
                else:
                    recipient_list.append(addr)
            
            message["To"] = ", ".join(recipient_list)
            message["Subject"] = subject

            # Add email body
            body_part = MIMEText(body_text, "plain", "utf-8")
            message.attach(body_part)

            # Add Markdown file as attachment using MIMEApplication
            # Follow the pattern: read as bytes and add Content-Disposition header only
            markdown_bytes = markdown_content.encode("utf-8")
            attachment = MIMEApplication(markdown_bytes)
            attachment.add_header('Content-Disposition', 'attachment', filename=attachment_filename)
            message.attach(attachment)

            # Connect to SMTP server
            if self.use_ssl:
                # Use SMTP_SSL for port 465
                server = smtplib.SMTP_SSL(self.config.smtp_server, self.config.smtp_port)
            else:
                # Use SMTP for port 587 (with STARTTLS)
                server = smtplib.SMTP(self.config.smtp_server, self.config.smtp_port)
                server.starttls()

            # Enable debug if logging level is DEBUG
            if logger.isEnabledFor(logging.DEBUG):
                server.set_debuglevel(1)

            # Login
            server.login(self.config.smtp_user, self.config.smtp_password)

            # Send email using as_bytes() method (more reliable for attachments)
            server.sendmail(from_email, to_addresses, message.as_bytes())
            server.quit()

            logger.info(f"Email with attachment sent successfully to {to_addresses}")
            return True

        except smtplib.SMTPException as e:
            logger.error(f"SMTP error while sending email: {e}")
            return False
        except Exception as e:
            logger.error(f"Failed to send email: {e}")
            return False

    def send_review_report(
        self, result: ReviewResult, markdown_content: str, review_config: dict
    ) -> bool:
        """
        Send review report via email with Markdown file as attachment.

        Args:
            result: ReviewResult object
            markdown_content: Markdown formatted review content
            review_config: Review configuration

        Returns:
            True if email sent successfully
        """
        # Check if email should be sent
        if not self.should_send_email(result.severity, review_config):
            logger.info(
                f"Email not sent for {result.repo_name}#{result.pr_number} "
                f"(severity: {result.severity})"
            )
            return False

        # Generate email body (brief summary)
        body_text = self.generate_email_body(result)

        # Generate subject
        severity_emoji = {
            "critical": "🔴",
            "high": "🟠",
            "medium": "🟡",
            "low": "🟢",
        }
        emoji = severity_emoji.get(result.severity, "📝")
        subject = f"{emoji} 代码审查报告: {result.repo_name}#{result.pr_number} - {result.pr_title}"

        # Generate attachment filename
        # Sanitize filename: replace invalid characters
        safe_repo_name = result.repo_name.replace("/", "_")
        safe_pr_title = result.pr_title.replace(" ", "_")[:50]  # Limit length
        attachment_filename = f"code_review_{safe_repo_name}_PR{result.pr_number}_{safe_pr_title}.md"

        # Send email with attachment
        return self.send_email_with_attachment(
            subject, body_text, markdown_content, attachment_filename, self.config.to_addresses
        )

